package com.ruoyi.common.utils;

import com.ruoyi.common.constant.Constants;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;

public class AESECBPKCS5Util{

	/**
	 * 密钥算法
	 */
	private static final String KEY_ALGORITHM = "AES";

	/**
	 * 加密/解密算法 / 工作模式 / 填充方式 Java 6支持PKCS5Padding填充方式 Bouncy Castle支持PKCS7Padding填充方式,当使用PKCS7Padding时，需要指定BC
	 */
	private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

	/**
	 * AES要求密钥长度为128位或192位或256位，java默认限制AES密钥长度最多128位
	 */
	public static String sKey = "";

	/**
	 * 编码格式
	 */
	public static final String ENCODING = "utf-8";

	static{
		// 如果是PKCS7Padding填充方式，则必须加上下面这行
		Security.addProvider(new BouncyCastleProvider());
	}

	/**
	 * AES加密
	 * 
	 * @param source 源字符串
	 * @param key 密钥
	 * @return 加密后的密文
	 * @throws Exception
	 */
	public static String encrypt(String source, String key) throws Exception{
		byte[] sourceBytes = source.getBytes(ENCODING);
		byte[] keyBytes = key.getBytes(ENCODING);
		// 当使用PKCS7Padding时，需要指定BC
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
		cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, KEY_ALGORITHM));
		byte[] decrypted = cipher.doFinal(sourceBytes);
		return Base64.encodeBase64String(decrypted);
	}

	/**
	 * 使用默认密钥加密
	 * 
	 * @param source
	 * @return
	 * @throws Exception
	 */
	public static String encrypt(String source) throws Exception{
		return encrypt(source, Constants.AES_KEY);
	}

	/**
	 * AES解密
	 * 
	 * @param encryptStr 加密后的密文
	 * @param key 密钥
	 * @return 源字符串
	 * @throws Exception
	 */
	public static String decrypt(String encryptStr, String key) throws Exception{
		byte[] sourceBytes = Base64.decodeBase64(encryptStr);
		byte[] keyBytes = key.getBytes(ENCODING);
		// 当使用PKCS7Padding时，需要指定BC
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
		cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, KEY_ALGORITHM));
		byte[] decoded = cipher.doFinal(sourceBytes);
		return new String(decoded, ENCODING);
	}

	/**
	 * 提供默认密钥的解密
	 * 
	 * @param encryptStr
	 * @return
	 * @throws Exception
	 */
	public static String decrypt(String encryptStr) throws Exception{
		return decrypt(encryptStr, Constants.AES_KEY);
	}

	public static void main(String[] args) throws Exception{
		String key = Constants.AES_KEY;

		// 加密
		long lStart = System.currentTimeMillis();
		String enString = AESECBPKCS5Util.encrypt("123", key);
		System.out.println("加密后的字串是：" + enString);

		long lUseTime = System.currentTimeMillis() - lStart;
		System.out.println("加密耗时：" + lUseTime + "毫秒");

		// 解密
		lStart = System.currentTimeMillis();
		String DeString = AESECBPKCS5Util.decrypt(enString, key);
		System.out.println("解密后的字串是：" + DeString);
		lUseTime = System.currentTimeMillis() - lStart;
		System.out.println("解密耗时：" + lUseTime + "毫秒");
	}

}
